package com.iplant.pdm.serviceImpl;

import com.iplant.base.po.OutResult;
import com.iplant.base.po.Pagination;
import com.iplant.base.po.ServiceResult;
import com.iplant.base.po.enums.ExceptionTypes;
import com.iplant.base.utils.general.StringUtils;
import com.iplant.basic.service.basicenum.bpm.BPMEventModule;
import com.iplant.basic.service.basicenum.bpm.TaskQueryType;
import com.iplant.basic.service.po.bms.BMSEmployee;
import com.iplant.basic.utils.Constants;
import com.iplant.pdm.service.FRMService;
import com.iplant.pdm.service.basicenum.bop.FPCRouteStatus;
import com.iplant.pdm.service.basicenum.fpc.FPCRouteBPMStatus;
import com.iplant.pdm.service.po.bop.FPCRoute;
import com.iplant.pdm.service.po.bop.FPCRouteBPM;
import com.iplant.pdm.serviceImpl.dao.fpc.FPCRouteBPMDAO;
import com.iplant.pdm.serviceImpl.dao.fpc.FPCRouteDAO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class FRMServiceImpl implements FRMService {

    //region 构造函数
    public FRMServiceImpl() {
        Constants.BPMServiceMap.put(BPMEventModule.BOP_AUDIT, this);
    }
    //endregion


    //region 单实例

    private static FRMService Instance = null;

    public static FRMService getInstance() {
        if (Instance == null)
            Instance = new FRMServiceImpl();

        return Instance;
    }


    //endregion


    //region 流程
    @Override
    public ServiceResult<FPCRouteBPM> BPM_QueryDefaultTask(BMSEmployee wLoginUser,
                                                           int wTaskID, int wEventID) {
        ServiceResult<FPCRouteBPM> wResult = new ServiceResult<>();
        wResult.Result = new FPCRouteBPM();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);


            Map<String, Object> wParams = new HashMap<String, Object>();

            wParams.put("UpFlowID", wLoginUser.ID);
            wParams.put("Status", "0");

            FPCRouteBPM wFPCRouteBPM = FPCRouteBPMDAO.getInstance().SelectPO(wLoginUser,
                    wParams, wErrorCode);
            if (wFPCRouteBPM != null && wFPCRouteBPM.ID > 0) {
                wFPCRouteBPM.FlowType = wEventID;
                wFPCRouteBPM.UpFlowID = wLoginUser.ID;
                wFPCRouteBPM.UpFlowName = wLoginUser.Name;
                wFPCRouteBPM.CreateTime = Calendar.getInstance();
                wFPCRouteBPM.EditTime = Calendar.getInstance();
                wResult.Result = wFPCRouteBPM;
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());

        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }


    @Override
    public ServiceResult<FPCRouteBPM> BPM_CreateTask(BMSEmployee wLoginUser,
                                                     BPMEventModule wEventID) {
        ServiceResult<FPCRouteBPM> wResult = new ServiceResult<>();
        wResult.Result = new FPCRouteBPM();
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            FPCRouteBPM wPo = new FPCRouteBPM();
            wPo.setUserInfo(wLoginUser);
            wPo.ID = 0;
            wPo.FlowType = wEventID.getValue();
            wPo.UpFlowID = wLoginUser.ID;
            wPo.UpFlowName = wLoginUser.Name;
            wPo.Status = 0;
            wPo.StatusText = "";
            wPo.CreateTime = Calendar.getInstance();
            wPo.EditTime = Calendar.getInstance();

            FPCRouteBPMDAO.getInstance().UpdatePo(wLoginUser, wPo, wErrorCode);

            wResult.Result = wPo;

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<FPCRouteBPM> BPM_SubmitTask(BMSEmployee wLoginUser,
                                                     FPCRouteBPM wData) {
        ServiceResult<FPCRouteBPM> wResult = new ServiceResult<>();
        wResult.Result = wData;
        try {
            OutResult<Integer> wErrorCode = new OutResult<>(0);

            Map<String, Object> wParams = new HashMap<String, Object>();
            wParams.put("ID", wData.RouteID);
            FPCRoute wFPCRoute = FPCRouteDAO.getInstance().SelectPO(wLoginUser, wParams,
                    wErrorCode);
            if (wFPCRoute == null || wFPCRoute.ID <= 0) {
                wResult.FaultCode += ExceptionTypes.Logic.getLabel();
                return wResult;
            }
            wFPCRoute.setUserInfo(wLoginUser);

            if (wData.Status == FPCRouteBPMStatus.Confirm.getValue()) {
                wData.StatusText = FPCRouteBPMStatus.Confirm.getLabel();
                //更新工艺路线的状态
                wFPCRoute.Status = FPCRouteStatus.AUDITED.getValue();
            } else {
                wFPCRoute.Status = FPCRouteStatus.AUDITING.getValue();
            }

            if (wData.Status == FPCRouteBPMStatus.Canceled.getValue()) {
                wData.StatusText = "已撤销";
                //更新工艺路线的状态
                wFPCRoute.Status = FPCRouteStatus.SAVED.getValue();
            }
            if (wData.Status == FPCRouteBPMStatus.Rejected.getValue()) {
                wData.StatusText = "已驳回";
                //更新工艺路线的状态
                wFPCRoute.Status = FPCRouteStatus.SAVED.getValue();
            }

            int wAffectRows = FPCRouteDAO.getInstance().UpdatePo(wLoginUser, wFPCRoute, wErrorCode);
            if (wAffectRows <= 0) {
                wResult.FaultCode += ExceptionTypes.DBSQL.getLabel();
                return wResult;
            }

            wData.setUserInfo(wLoginUser);
            wData.EditTime = Calendar.getInstance();
            wAffectRows = FPCRouteBPMDAO.getInstance().UpdatePo(wLoginUser, wData, wErrorCode);
            if (wAffectRows <= 0) {
                wResult.FaultCode += ExceptionTypes.DBSQL.getLabel();
                return wResult;
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }

    @Override
    public ServiceResult<FPCRouteBPM> BPM_GetTask(BMSEmployee wLoginUser, int wID) {
        ServiceResult<FPCRouteBPM> wResult = new ServiceResult<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        wResult.Result = FPCRouteBPMDAO.getInstance().SelectPO(wLoginUser, wID, "", wErrorCode);
        wResult.AddFaultCode(wErrorCode);
        return wResult;
    }

    @Override
    public Class<FPCRouteBPM> GetTClass() {
        return FPCRouteBPM.class;
    }


    @Override
    public ServiceResult<List<FPCRouteBPM>> BPM_QueryEmployeeAllWeb(BMSEmployee wLoginUser, Map<String,
            Object> wParams, Pagination wPagination) {
        ServiceResult<List<FPCRouteBPM>> wResult = new ServiceResult<>();
        wResult.Result = new ArrayList<>();
        OutResult<Integer> wErrorCode = new OutResult<>(0);
        try {
            int wStatus = StringUtils.parseInt(wParams.get("Status"));
            switch (wStatus) {
                case 0://待办
                    wParams.remove("CStartTime");
                    wParams.remove("CEndTime");
                    wParams.remove("DStartTime");
                    wParams.remove("DEndTime");
                    wParams.put("Status", "1,2,3");
                    wResult.Result = FPCRouteBPMDAO.getInstance().SelectPOList(wLoginUser, wParams, wPagination,
                            wErrorCode);
                    break;
                case 1://已办
                    wParams.put("Status", "20,21,22");
                    wResult.Result = FPCRouteBPMDAO.getInstance().SelectPOList(wLoginUser, wParams, wPagination,
                            wErrorCode);
                    break;
                default://全部
                    wParams.put("Status", "1,2,3,20,21,22");
                    wResult.Result = FPCRouteBPMDAO.getInstance().SelectPOList(wLoginUser, wParams, wPagination,
                            wErrorCode);
                    break;
            }

            if (wResult.Result.size() == 0 || wStatus == 1) {
                return wResult;
            }

            // 待办数据处理
            List<FPCRouteBPM> wBaseList =
                    FPCRouteBPMDAO.getInstance().BFC_GetUndoTaskList(wLoginUser,
                            wLoginUser.ID,
                            new ArrayList<>(Collections.singletonList(BPMEventModule.BOP_AUDIT.getValue()))
                            , wParams, Pagination.getNewMaxSize(), wErrorCode);
            if (wBaseList == null || wBaseList.size() == 0) {
                return wResult;
            }
            for (FPCRouteBPM wTaskBase : wBaseList) {
                wTaskBase.TagTypes = TaskQueryType.ToHandle.getValue();
                for (int i = 0; i < wResult.Result.size(); i++) {
                    if (wResult.Result.get(i).ID == wTaskBase.ID)
                        wResult.Result.set(i, wTaskBase);
                }
            }

            wResult.setFaultCode(ExceptionTypes.getEnumType(wErrorCode.Result).getLabel());
        } catch (Exception e) {
            wResult.FaultCode += e.toString();
            log.error(e.toString());
        }
        return wResult;
    }


    //endregion
}
